Semantik Web • Hafta 06
OWL-S: Semantik Web Servisleri
Profile, Process Model, Grounding ve alerji öneri servisinin Java ile uçtan uca kurulması
Lisansüstü Semantik Web Dersi • CMPE 583
Hafta 06 • Kazanımlar
Bu hafta sonunda
- WSDL ile OWL-S arasındaki farkı örnekle açıklayabileceksiniz.
- Bir servisi Profile / Process Model / Grounding olarak üç katmanda tanımlayabileceksiniz.
- IOPE (girdi, çıktı, önkoşul, etki) modelini alerji servisine uygulayabileceksiniz.
- Java ile servis arka ucunu ontolojiye bağlayabileceksiniz.
- Servis keşfi ve kompozisyonun neden ontoloji gerektirdiğini gösterebileceksiniz.
01
Ödev 5'in Çözümü
Kapanış aksiyomu, güvenli ürün ve ilk Java çalıştırması.
Çözüm 5.1 — LactoseSafeProduct
EAN_00001 Type
Contain only {Alginic_Acid}
LactoseSafeProduct EquivalentTo
Product and
(Contain only
(not (Triggers value Lactose)))
EAN_00001 → LactoseSafe ✓
EAN_00004 → karar yok
(kapanış aksiyomu yok)
Kapanış olmadan açık dünya "başka katkı olabilir" der; güvenlik iddiası çıkmaz.
Çözüm 5.2 — Beklenen konsol çıktısı
Aksiyom sayisi: 118
Siniflar: Person Product FoodAdditives Allergy Adult PersonAtRisk
Person bireyleri: TC_001 TC_002 TC_003 TC_004
Eklenen aksiyom: Product SubClassOf (Contain some FoodAdditives)
Tutarli mi? true
Yazildi: /home/proje/ALLERGY_STEP5.owl
Aksiyom sayısı eklemeden sonra artmalıdır; artmıyorsa addAxiom yanlış ontolojiye uygulanmıştır.
02
Web Servisinden Semantik Servise
WSDL neyi çözer, neyi çözmez?
WSDL: sözdizimsel sözleşme
<operation name="checkProduct">
<input message="tns:CheckRequest"/>
<output message="tns:CheckResponse"/>
</operation>
<xs:element name="tc" type="xs:string"/>
<xs:element name="ean" type="xs:string"/>
<xs:element name="risk" type="xs:boolean"/>
- Nerede çağrılır, hangi tipleri alır — bunu söyler.
- Ne yaptığını söylemez: "checkProduct" bir metindir.
- risk bir boolean; anlamı belgede, kodda değil.
- Otomatik keşif ve kompozisyon mümkün değildir.
OWL-S'in üç hedefi
Otomatik keşif
"Alerji riski hesaplayan bir servis bul" — tür bazlı arama.
Otomatik çağırma
Girdi türleri ontolojik olduğu için eşleme koda gömülmez.
Otomatik kompozisyon
Profil çıktısı bir sonrakinin girdisine uyuyorsa zincir kurulur.
Ortak nokta: servisin girdisi ve çıktısı ontolojideki sınıflar ile tiplenir — xs:string değil Person, Product, Allergy.
OWL-S üst ontolojisi: üç soru
| Katman | Cevapladığı soru | Alerji servisinde |
| Profile | Servis ne yapar? | Kişi + ürün → risk raporu |
| Process Model | Nasıl çalışır? | Profil oku → içerik oku → kural çalıştır → rapor |
| Grounding | Nasıl çağrılır? | REST/SOAP uç noktası + XSD eşlemesi |
Service ──presents──▶ ServiceProfile
──describedBy──▶ ServiceModel
──supports──▶ ServiceGrounding
Servis kökü: AllergyCheckService
<service:Service rdf:ID="AllergyCheckService">
<service:presents rdf:resource="#AllergyCheckProfile"/>
<service:describedBy rdf:resource="#AllergyCheckProcess"/>
<service:supports rdf:resource="#AllergyCheckGrounding"/>
</service:Service>
Üç işaretçi. Servis tanımı, projedeki ALLERGY_FIXED.owl ontolojisini import ederek onun sınıflarını tip olarak kullanır.
Profile: reklam panosu
<profile:Profile rdf:ID="AllergyCheckProfile">
<profile:serviceName>Allergy Risk Check</profile:serviceName>
<profile:textDescription>
Kisinin alerji profili ile sectigi urunun katki maddelerini
karsilastirir; riskli katkilari ve risk durumunu dondurur.
</profile:textDescription>
<profile:hasInput rdf:resource="#PersonIn"/>
<profile:hasInput rdf:resource="#ProductIn"/>
<profile:hasOutput rdf:resource="#RiskOut"/>
<profile:hasPrecondition rdf:resource="#HasAllergyProfile"/>
<profile:hasResult rdf:resource="#RiskAsserted"/>
</profile:Profile>
Keşif motoru yalnızca bu bölümü okur: girdi/çıktı türleri eşleşiyorsa servis aday olur.
IOPE: dört bileşen
| Bileşen | Anlamı | Alerji servisinde |
| Input | Gerekli veri | Person bireyi, Product bireyi |
| Output | Üretilen veri | Riskli katkı listesi, risk durumu |
| Precondition | Çağrı öncesi doğru olmalı | Kişinin en az bir alerjisi bildirilmiş |
| Effect | Çağrı sonrası dünya değişir | PersonAtRisk üyeliği ontolojiye yazılır |
Etki, bizim projede gerçektir: infer() sonrası aksiyomlar dosyaya kalıcı yazılır.
Parametreler ontolojiyle tiplenir
<process:Input rdf:ID="PersonIn">
<process:parameterType
rdf:datatype="&xsd;anyURI">http://EMU/AllergyOntology#Person
</process:parameterType>
</process:Input>
<process:Output rdf:ID="RiskOut">
<process:parameterType
rdf:datatype="&xsd;anyURI">http://EMU/AllergyOntology#PersonAtRisk
</process:parameterType>
</process:Output>
Fark burada: WSDL'de girdi string'dir, OWL-S'te Person sınıfıdır. Alt sınıflar da (örn. Adult) otomatik kabul edilir.
Önkoşul ve etki SWRL ile yazılır
Precondition
Person(?p) ^
hasAllergy(?p, ?a)
→ CanBeChecked(?p)
Effect
Effected_Allergen(?p, ?f)
→ PersonAtRisk(?p)
Etki ifadesi, projedeki S7 kuralının aynısıdır. OWL-S servis tanımı ile SWRL kural tabanı aynı ontolojiyi paylaşır — bu yüzden servis sözleşmesi ile uygulama davranışı ayrışmaz.
Process Model: atomik süreç
<process:AtomicProcess rdf:ID="CheckRiskProcess">
<process:hasInput rdf:resource="#PersonIn"/>
<process:hasInput rdf:resource="#ProductIn"/>
<process:hasOutput rdf:resource="#RiskOut"/>
</process:AtomicProcess>
| Süreç türü | Anlamı |
| AtomicProcess | Tek çağrı, doğrudan çalıştırılabilir |
| SimpleProcess | Soyut; doğrudan çağrılamaz |
| CompositeProcess | Kontrol yapısıyla birleşen alt süreçler |
Kontrol yapıları
| Yapı | Davranış | Alerji senaryosu |
| Sequence | Sırayla | Profil oku → içerik oku → kural çalıştır |
| Split | Paraleldir, beklemez | Log kaydı + bildirim |
| Split-Join | Paralel, hepsini bekler | Katkı ve besin değeri servisleri |
| If-Then-Else | Koşullu | Risk varsa alternatif ürün öner |
| Repeat-While | Döngü | Sepetteki her ürün için tekrar |
| Choice | Biri seçilir | Yerel ontoloji ya da uzak SPARQL uç noktası |
Bileşik süreç: dört adımlı akış
<process:CompositeProcess rdf:ID="AllergyCheckProcess">
<process:composedOf>
<process:Sequence>
<process:components rdf:parseType="Collection">
<process:AtomicProcess rdf:about="#LoadPersonProfile"/>
<process:AtomicProcess rdf:about="#LoadProductContent"/>
<process:AtomicProcess rdf:about="#RunSWRLRules"/>
<process:AtomicProcess rdf:about="#BuildRiskReport"/>
</process:components>
</process:Sequence>
</process:composedOf>
</process:CompositeProcess>
Bu dört adım, Java tarafındaki dört metoda birebir karşılık gelecek.
Adımlar arasında veri akışı
LoadPersonProfileout: allergies[] , chosenProduct
LoadProductContentin: chosenProduct → out: additives[]
RunSWRLRulesin: allergies[], additives[] → out: effectedAllergens[]
BuildRiskReportout: riskLevel , explanation
OWL-S'te bu bağlar process:Binding ile bildirilir; kodda parametre geçişine dönüşür.
Grounding: soyuttan somuta
<grounding:WsdlAtomicProcessGrounding rdf:ID="CheckRiskGrounding">
<grounding:owlsProcess rdf:resource="#CheckRiskProcess"/>
<grounding:wsdlOperation>checkProduct</grounding:wsdlOperation>
<grounding:wsdlInputMessage>CheckRequest</grounding:wsdlInputMessage>
<grounding:wsdlInput>
<grounding:WsdlInputMessageMap>
<grounding:owlsParameter rdf:resource="#PersonIn"/>
<grounding:wsdlMessagePart>tc</grounding:wsdlMessagePart>
</grounding:WsdlInputMessageMap>
</grounding:wsdlInput>
</grounding:WsdlAtomicProcessGrounding>
Ontolojik Person parametresi, tel üzerinde tc adlı bir string'e indirilir. Kayıp anlamı geri kazanmak Grounding'in işidir.
03
Java ile Servis Bağlantısı
Ontoloji erişim katmanından REST uç noktasına.
Servisin Java mimarisi
EndpointAllergyServiceEndpoint
HTTP / JSON
ServisAllergyCheckService
4 adımlı akış
Ontoloji erişimiOntologyGateway
OWL API
ÇıkarımHermiT + SWRL/Drools
Kural: uç nokta ontolojiyi bilmez. Bütün IRI bilgisi Gateway'de kapsüllenir; böylece ontoloji değişince yalnızca tek sınıf değişir.
Adım 1 — OntologyGateway
public class OntologyGateway {
public static final String NS = "http://EMU/AllergyOntology#";
private final OWLOntologyManager man = OWLManager.createOWLOntologyManager();
private final OWLDataFactory df = man.getOWLDataFactory();
private final OWLOntology ont;
public OntologyGateway(File owlFile) throws Exception {
this.ont = man.loadOntologyFromOntologyDocument(owlFile);
}
OWLNamedIndividual ind(String s) { return df.getOWLNamedIndividual(iri(s)); }
OWLObjectProperty op (String s) { return df.getOWLObjectProperty(iri(s)); }
OWLClass cls(String s) { return df.getOWLClass(iri(s)); }
private static IRI iri(String local) { return IRI.create(NS + local); }
String shortForm(OWLIndividual i) { return i.asOWLNamedIndividual().getIRI().getShortForm(); }
}
Adım 2 — LoadPersonProfile
public Set<String> allergiesOf(String tc) {
OWLNamedIndividual p = ind(tc);
return EntitySearcher.getObjectPropertyValues(p, op("hasAllergy"), ont)
.stream()
.map(v -> v.asOWLNamedIndividual().getIRI().getShortForm())
.collect(Collectors.toSet());
}
public String chosenProductOf(String tc) {
return EntitySearcher
.getObjectPropertyValues(ind(tc), op("ChooseProduct"), ont)
.stream().findFirst()
.map(v -> v.asOWLNamedIndividual().getIRI().getShortForm())
.orElse(null);
}
allergiesOf("TC_003") → [Fish, Lactose] chosenProductOf("TC_003") → EAN_00003
Adım 3 — LoadProductContent
public Map<String, Set<String>> additivesWithTriggers(String ean) {
Map<String, Set<String>> result = new LinkedHashMap<>();
for (OWLIndividual add : EntitySearcher
.getObjectPropertyValues(ind(ean), op("Contain"), ont)) {
result.put(shortForm(add), EntitySearcher
.getObjectPropertyValues(add, op("Triggers"), ont).stream()
.map(this::shortForm).collect(Collectors.toSet()));
}
return result;
}
EAN_00003 → { Casein=[Lactose], Sodium_Ascorbite=[Fish] }
Adım 4 — RunSWRLRules
public void runRules() throws SWRLRuleEngineException {
SWRLRuleEngine engine =
SWRLAPIFactory.createSWRLRuleEngine(ont); // Drools tabanli
engine.infer(); // kural ciktilari ontolojiye yazilir
}
public Set<String> effectedAllergens(String tc) {
return EntitySearcher
.getObjectPropertyValues(ind(tc), op("Effected_Allergen"), ont)
.stream()
.map(v -> v.asOWLNamedIndividual().getIRI().getShortForm())
.collect(Collectors.toSet());
}
infer() çağrısı OWL-S tarafındaki Effect'in gerçekleşmesidir: dünya değişir, aksiyom eklenir. Ayrıntısı Hafta 10'da.
Adım 5 — BuildRiskReport
public RiskReport check(String tc) throws Exception {
Set<String> allergies = allergiesOf(tc);
String ean = chosenProductOf(tc);
Map<String, Set<String>> content = additivesWithTriggers(ean);
runRules();
Set<String> guilty = effectedAllergens(tc);
String level = guilty.isEmpty() ? "SAFE" : "AT_RISK";
return new RiskReport(tc, ean, allergies, content, guilty, level);
}
check("TC_001") → AT_RISK , guilty = [Nisin] , ean = EAN_00004
Adım 6 — REST uç noktası (Grounding)
@Path("/allergy")
public class AllergyServiceEndpoint {
private static final AllergyCheckService SERVICE =
new AllergyCheckService(new File("ALLERGY_FIXED.owl"));
@GET @Path("/check")
@Produces(MediaType.APPLICATION_JSON)
public RiskReport check(@QueryParam("tc") String tc,
@QueryParam("ean") String ean) throws Exception {
return SERVICE.check(tc, ean);
}
}
GET /allergy/check?tc=TC_001&ean=EAN_00004
Servisin döndürdüğü rapor
{
"person" : "TC_001",
"name" : "Ayse",
"product" : "EAN_00004",
"allergies": ["Lactose"],
"content" : { "Ascorbic_Acid": [],
"Nisin": ["Lactose"],
"Soy_Lecitin": ["Egg"] },
"guilty" : ["Nisin"],
"riskLevel": "AT_RISK",
"rules" : ["S3_LactoseNisin", "S6_GenericAllergen", "S7_RiskClass"]
}
rules alanı Proof katmanının basit karşılığıdır: sonucun gerekçesi taşınır.
Kompozisyon: alternatif ürün önerisi
public List<String> suggestAlternatives(String tc) {
Set<String> allergies = allergiesOf(tc);
List<String> safe = new ArrayList<>();
for (String ean : allProducts()) {
boolean risky = additivesWithTriggers(ean).values().stream()
.flatMap(Set::stream)
.anyMatch(allergies::contains);
if (!risky) safe.add(ean);
}
return safe;
}
suggestAlternatives("TC_001") → [EAN_00001, EAN_00002]
Servis keşfi: eşleşme dereceleri
| Derece | Koşul | Örnek |
| Exact | İstenen tür = sunulan tür | Person → Person |
| Plug-in | Sunulan daha genel | Adult isteyen, Person kabul eden servis |
| Subsume | Sunulan daha özel | Person isteyen, yalnızca Adult kabul eden servis |
| Fail | İlişki yok | Product ↔ Allergy |
Bu dereceleri hesaplayan şey reasoner'dır: isSubClassOf sorgularıyla uyum ölçülür — metin benzerliği ile değil.
Java ile tür uyumu denetimi
OWLReasoner r = new ReasonerFactory().createReasoner(ont);
OWLClass requested = cls("Adult"); // istemcinin verdigi tur
OWLClass offered = cls("Person"); // servisin bekledigi tur
boolean plugIn = r.getSuperClasses(requested, false)
.containsEntity(offered);
System.out.println(plugIn ? "PLUG_IN uyum: servis kullanilabilir"
: "uyum yok");
PLUG_IN uyum: servis kullanilabilir
OWL-S'in alternatifleri
| Yaklaşım | Özelliği | Bugünkü durum |
| OWL-S | Tam ontolojik servis modeli | W3C Submission; akademik referans |
| WSMO / WSML | Hedef odaklı, arabuluculuk katmanı | Araştırma |
| SAWSDL | WSDL'e anlamsal ek açıklama | W3C Recommendation; hafif |
| Hydra / JSON-LD | REST + bağlı veri | Pratikte en yaygın modern yol |
Dersin amacı model kurmayı öğretmek: OWL-S'in üç katmanı, hangi teknolojiyi seçerseniz de sorulacak soruları verir.
Protégé'de servis ontolojisi
Active ontologyEntitiesIndividuals by class
Imported ontologies
service.owl
profile.owl
process.owl
grounding.owl
ALLERGY_FIXED.owl
Individuals: Service
AllergyCheckService
presents
AllergyCheckProfile
describedBy
AllergyCheckProcess
Şematik gösterim. Kritik nokta: alerji ontolojisinin import edilmesi — parametre türleri oradan gelir.
04
Ödev ve Proje Adımı
Kendi öneri servisinizi tanımlayın ve Java ile bağlayın.
Ödev 6 — Öneri servisi
- Bir ProductRecommendationService için Profile yazın (IOPE tam olsun).
- Process Model'i Sequence + If-Then-Else ile kurun.
- Grounding'te parametre eşlemesini bildirin.
- Java'da OntologyGateway üzerinden servis metodunu yazın.
- Üç kişi için servisi çağırıp raporu JSON olarak üretin.
Teslim
Servis ontolojisi (3 dosya) + Java sınıfları + 3 örnek JSON çıktısı + 3 sayfa rapor.
Çözümü Hafta 07'nin başında ele alacağız.
Değerlendirme ölçütleri
| Ölçüt | Ağırlık | Beklenen |
| Profile / IOPE | 25% | Girdi-çıktı ontolojik tiplenmiş |
| Process Model | 20% | Kontrol yapısı gerekçeli |
| Grounding | 15% | Parametre eşlemesi tam |
| Java bağlantısı | 25% | Servis gerçekten çalışıyor |
| Rapor ve gerekçe | 15% | Kural izleri raporda |
Kaynaklar
- W3C — OWL-S: Semantic Markup for Web Services, Member Submission (2004).
- Martin, D. et al. — Bringing Semantics to Web Services: The OWL-S Approach.
- W3C — SAWSDL: Semantic Annotations for WSDL and XML Schema.
- Paolucci, M. et al. — Semantic Matching of Web Services Capabilities.
- OWL API belgeleri — EntitySearcher ve reasoner arayüzleri.
Özet • 1 / 2
OWL-S modeli
- WSDL nasıl çağrılacağını, OWL-S ne yaptığını söyler.
- Üç katman: Profile (ne), Process Model (nasıl), Grounding (hangi uçtan).
- IOPE'nin etkisi projede gerçektir: infer() ontolojiyi değiştirir.
- Parametreler ontolojik sınıflarla tiplenir; alt sınıflar otomatik uyar.
Özet • 2 / 2
Java tarafı ve sonraki adım
- Gateway bütün IRI bilgisini kapsüller; uç nokta ontolojiyi bilmez.
- Dört süreç adımı, dört Java metoduna karşılık gelir.
- Keşif eşleşmesini reasoner hesaplar, metin benzerliği değil.
- Rapora kural izlerini koymak Proof katmanının pratik hâlidir.
Hafta 07'de
SWRL: kural sözdizimi, built-in'ler, DL-safe kısıt ve projedeki yedi kuralın (S1–S7) tam çözümlemesi.
Ayrıca: Ödev 6'nın ayrıntılı çözümü.
Tekrar Soruları
Kendinizi sınayın
- WSDL neden otomatik keşfe yetmez?
- Profile ile Process Model arasındaki iş bölümü nedir?
- Precondition ile Effect'i hangi dille yazdık?
- Plug-in eşleşmesi ne zaman oluşur?
- Grounding'de hangi bilgi kaybolur, nasıl geri kazanılır?
- Gateway sınıfı hangi değişikliği izole eder?
- rules alanı hangi katmana karşılık gelir?
- SAWSDL ile OWL-S arasındaki temel tercih nedir?
Alıştırma • Sınıf içi
Servisi genişletin
Servise "kişinin BMI değerine göre uyarı" adımı eklenecek.
hasInput → ______
hasOutput → ______
precondition → ______
effect → ______
Sorular
- Bu adım Sequence'in neresine girer?
- BMI hesaplanmamışsa önkoşul nasıl yazılır?
- Hangi Java metodu eklenmeli?
Çözüm Hafta 07'de.